home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * COPYRIGHT 1990,91,92 BY GRACILIS INC.
- *
- * 623 Palace St.
- * Aurora, Il. 60506
- *
- * (708)-801-8800 Office
- * (708)-844-0183 (FAX - Support BBS)
- *
- * GRACILIS, INC., MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS
- * SOFTWARE FOR ANY PURPOSE.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
- *
- * Permission is granted for non-commercial use/distribution only, as long as
- * this copyright header is included intact and unaltered.
- *
- ******************************************************************************/
-
- /*****************************************************************************
- *
- *
- * File: twin_at.c
- *
- * Rev : 3.0
- *
- * Description:
- *
- * This File contains routines that implement PackeTwin
- * synchronous SCC driver with an interface to KA9Q's TCP/IP suite.
- *
- *
- * Routines:
- *
- * tsync_attach - Performs attach functions for TCP/IP, i.e.
- * attach the tsync_driver to TCP/IP.
- *
- * do_tsync_stat - Applications' routine for "displaying" the
- * tsync_driver statistics.
- *
- * tsync_ioctl - Set the IO Control parameters.
- *
- *
- * Revision History:
- *
- * Release 2.0 - 9/7/92 First Release of cleaned up Twin driver
- * with fewer files, and called twin_at instead
- * of tsync_at
- *
- * Release 2.1 - 9/12/92 Fix bug in half-duplex dma mode, which caused
- * loss of every other receive frame in a multi-
- * frame transmission.
- */
-
-
- #include <stdio.h>
- #include <dos.h>
- #include "global.h"
- #include "config.h"
- #include "hardware.h"
- #include "mbuf.h"
- #include "iface.h"
- #include "ax25.h"
- #include "trace.h"
- #include "netuser.h"
- #include "proc.h"
- #include "pktdrvr.h"
- #include "devparams.h"
- #include "z8530.h"
- #include "gracilis.h"
- #include "twin.h"
-
-
- /* If using the Borland stdio library... */
- #ifdef OLD_KA9Q
- #else
- /* If using the new KA9Q stdio library... */
- #define tprintf printf
- #endif
-
-
- /*******************************************************************
- * TSYNC_ATTACH *
- * *
- * File: tsync_at.c *
- * Rev : 3.0 *
- * *
- ********************************************************************
- *
- *
- * DESCRIPTION:
- * -----------
- * Attaches the PackeTwin's synchronous SCC driver to TCP/IP.
- *
- * ARGUMENTS:
- * ---------
- * All argv's are strings
- * argv[0]: hardware type, "tsync"
- * argv[1]: "0" = 8530 SCC A
- * "1" = 8530 SCC B
- * argv[2]: vector, Interrupt request line #
- *
- * argv[3]: IOBASE : base address for PackeTwin default 0x230
- *
- * argv[4]: "HDX" half-duplex
- * "FDX" full-duplex
- *
- * argv[5]: mode, DMA/INTS for channel 1, MUST be INTS
- *
- * argv[6]: Dma channel to use for receive...
- * 0 = none...
- * 1 = Rx on dma channel 1 and if FULL DUPLEX tx on channel 3
- * 3 = Rx on dma channel 3 and if FULL DUPLEX tx on channel 1
- *
- * argv[7]: interface label
- *
- * This label is provided by the user and the attach uses
- * it in its tprintf's to tell the user which interface
- * is being talked about.
- *
- * argv[8]: max receive packet buffer size in bytes
- * argv[9]: max xmit packet buffer size in bytes
- * argv[10]: interface baud rate, e.g, "9600"
- * argv[11]: OPTIONAL - clocking options
- * argv[12]: OPTIONAL - clocking options
- * argv[13]: OPTIONAL - Data Encoding: NRZ/NRZI
- * argv[14]: OPTIONAL - IP address - default is Ip_addr
- * argv[15]: OPTIONAL - number of RX buffers to pre-allocate
- *
- * RETURN VALUES:
- * -------------
- * 0 - success
- * -1 - failure, driver not attached and no memory left allocated
- *
- * GLOBAL INPUTS:
- * -------------
- *
- * GLOBAL OUTPUTS:
- * --------------
- *
- * FUNCTIONS CALLED:
- * ----------------
- * tprintf
- * calloc
- * malloc
- * tsync_hwinit
- * free
- *
- * IO:
- * --
- *
- *
- ******************************************************************/
-
-
-
- /* Extern declaration for the */
- extern UNI_DCB Twin_udcb[]; /* array of universal control */
- /* blocks for this driver */
-
- /* interrupt handler */
- extern INTERRUPT twinvec();
-
- extern INTERRUPT (*Twin_oldvec) __ARGS((void)); /* Old vector contents */
- extern INTERRUPT (*Twin_handler) __ARGS((void));
-
-
- extern char *Twin_dvr_version;
- extern int Twin_io_base;
-
-
- extern int16 Twin_vector;
- extern int Twin_cputype; /* Global to identify the machine type */
- /* 0 = 8086 */
- /* 2 = 80286 */
- /* 3 = 80386 */
-
- int
- tsync_attach(argc,argv,p)
- int argc;
- char *argv[];
- void *p; /* new for NOS */
- {
- extern void tsyncvec();
-
- extern struct iface *ifaces;
- char i_state;
- int32 ipaddr; /* new for NOS - IP address */
- int i;
- char tmpbuf[80];
- register struct iface *intfc_p;
- DCB *dcbp;
- UNI_DCB *udcbp;
- int udcb_dev;
- int16 rbufsize, xbufsize;
- int rxdmachan,txdmachan;
- struct drv_timer *timer1;
- unsigned char far *cpusig_ptr; /* ptr to CPU signature byte in rom */
-
- bool hdxflg,dmaflg;
- #ifdef OLD_KA9Q
- struct phdr *hdr; /* new for NOS - packet header*/
- #endif
-
- void tsync_recv(), tsync_txisr(), tsync_rxisr(), tsync_xstatisr();
-
- int32 tsync_ioctl();
- int tsync_send();
- int tsync_output();
- int tsync_stop();
- int tsync_raw();
- int ax_send();
- int ax_output();
-
-
-
- /* Try reading the Machine ID in ROM... */
- cpusig_ptr = (unsigned char *)MK_FP(0xf000,0xfffe);
-
- if((*cpusig_ptr == 0xfc) || (*cpusig_ptr == 0xf8))
- Twin_cputype = 2; /* 80286 or better */
-
- else Twin_cputype = 0; /* Default to type 8086 */
-
-
- #ifdef TSYNC_DEBUG_PRT
- printf("tsync_attach: argument count is %d\n",argc);
- for(i=0;i<argc;i++)
- printf("arg #%d: %s\n",i,argv[i]);
- printf("\n\n");
- #endif
-
-
- /*
- * validate input params
- */
- if ( argc < 11 )
- {
- tprintf("tsync_attach: too few arguments (%d) \n", argc);
-
- tprintf("tsync <chan> <vec> <iobase> <hdx|fdx> <dma|ints> <rx dmachan>\n");
- tprintf(" <name> <rxsize> <txsize> <speed> [txclk] [rxclk] [nrz|nrzi] \n");
- tprintf(" [ipaddr] [#rxbufs]\n");
- return(1); /* should this be a -1, milt milt */
- }
-
- /* get the PackeTwin device number/address
- * and validate it for a synchronous driver
- */
- udcb_dev = htoi(argv[1]);
-
- /* range check device number */
- if ( (udcb_dev < 0) || (udcb_dev > 1) )
- {
- tprintf("tsync_attach error: Channel number %x out of range!\n", udcb_dev);
- return(-1);
- }
-
- udcbp = &Twin_udcb[udcb_dev]; /* dev num is index number!!! */
-
- /* See if already attached */
- if ( udcbp->attached == TRUE )
- {
- tprintf("tsync_attach error: Channel %s already attached; interface is %s", argv[1], argv[7]);
- return(-1);
- }
-
-
- if ( if_lookup(argv[7]) != NULLIF ) /* new for NOS */
- {
- tprintf("Interface %s already exists \n", argv[7]);
- return(-1);
- }
-
- Twin_vector = htoi(argv[2]);
-
- if( Twin_vector <= 0 || Twin_vector > 15)
- {
- tprintf("Illegal vector specified: %s\n", argv[2]);
- return(-1);
-
-
- }
-
- if((htoi(argv[3])) >= 0x100)
- Twin_io_base = htoi(argv[3]);
- else
- {
- tprintf("Illegal iobase specified: %s\n", argv[3]);
- return(-1);
- }
-
- if(strcmpi(argv[4],"hdx") == 0) hdxflg = TRUE;
- else if(strcmpi(argv[4],"fdx") == 0) hdxflg = FALSE;
- else
- {
- tprintf("tsync_attach error: Specified %s instead of \"hdx\" or \"fdx\" for interface %s\n",
- argv[4],argv[7]);
- return(-1);
- }
-
- /* Are we in DMA mode? */
- if (strcmpi(argv[5],"dma") == 0)
- {
- dmaflg = TRUE;
- rxdmachan = htoi(argv[6]);
-
- /* Did they enter a valid dma channel #? */
- if((rxdmachan != 3) && (rxdmachan != 1))
- {
- /* NO... bad channel # */
- tprintf("tsync_attach error: Specified dma channel: %d instead of 1 or 3 for interface %s\n",
- rxdmachan,argv[7]);
- return(-1);
- }
-
- /* YES valid channel # */
- else
- {
- if(hdxflg == FALSE)
- {
- if(rxdmachan == 1)txdmachan = 3;
- else txdmachan = 1;
- }
- else txdmachan = rxdmachan;
- }
- }
-
- /* in interrupt mode? */
- else if (strcmpi(argv[5],"ints") == 0)dmaflg = FALSE;
- else
- {
- tprintf("tsync_attach error: Specified %s instead of \"dma\" or \"ints\" for interface %s\n",
- argv[5],argv[7]);
- return(-1);
- }
-
- /* Can't specify DMA for port B */
- if((dmaflg == TRUE) && (udcb_dev != 0))
- {
- tprintf("tsync_attach error: DMA is not supported on channel 1!\n");
- return(-1);
- }
-
- if ( (rbufsize = atoi(argv[8])) == 0 )
- {
- tprintf("tsync_attach error: Receive buffer size error %s, interface %s\n",
- argv[8],argv[7]);
- return(-1);
- }
-
- if ( (xbufsize = atoi(argv[9])) == 0 )
- {
- tprintf("tsync_attach error: Transmit buffer size error %s, interface %s\n",
- argv[9],argv[7]);
- return(-1);
- }
-
-
- /* new for NOS, Set the IP address */
- ipaddr = Ip_addr; /* default value */
- if ( argc >= 15 )
- ipaddr = resolve(argv[14]);
- if ( ipaddr == 0 )
- {
- tprintf(Noipaddr);
- return(-1);
- }
-
-
- /*
- * try to allocate necessary memory
- */
- intfc_p = (struct iface *)calloc(1,sizeof(struct iface));
- if ( intfc_p != (struct iface *)NULLBUF )
- {
- intfc_p->name = malloc((unsigned int)strlen(argv[7])+2);
- if (intfc_p->name != (char *)NULLBUF )
- {
- /* device hw addr */
- intfc_p->hwaddr = malloc(AXALEN);
- if ( intfc_p->hwaddr == NULLCHAR )
- {
- free(intfc_p->name);
- free(intfc_p);
- tprintf("tsync_attach error: no memory for interface hwaddr, size of sizeof(struct mycall) bytes, interface %s", argv[7]);
- return(-1);
- }
-
- }
- else
- {
- free(intfc_p);
- tprintf("tsync_attach error: no memory for interface name, size 7 bytes, interface %s", argv[7]);
- return(-1);
- }
- }
- else
- {
- tprintf("tsync_attach error: no memory for interface struct, size of sizeof(struct iface), interface %s", argv[7]);
- return(-1);
- }
-
- /* get the timer control blocks */
- /* must have zeros in structure, so use calloc */
- if ( (timer1 = (struct drv_timer *)calloc(1,sizeof(struct drv_timer))) == (struct drv_timer *)NULLBUF )
- {
- free(intfc_p->hwaddr);
- free(intfc_p->name);
- free(intfc_p);
- tprintf("tsync_attach error: no memory for timer control block structure, size of sizeof(struct drv_timer), interface %s", argv[7]);
- return(-1);
- }
-
-
- dcbp = (DCB *)calloc(1,sizeof(DCB)); /* zero-out the dcb */
- if ( dcbp != (DCB *)NULLBUF )
- {
- dcbp->rxbufsize = rbufsize;
- #ifdef OLD_KA9Q
- dcbp->rxbufp = alloc_mbuf(rbufsize+sizeof(struct phdr));
- #else
- dcbp->rxbufp = alloc_mbuf(rbufsize);
- #endif
- if (dcbp->rxbufp != NULLBUF )
- {
- dcbp->ioctlparams = (struct tsync_ioctl *)malloc(sizeof(struct tsync_ioctl));
- if ( dcbp->ioctlparams == (struct tsync_ioctl *)NULLBUF )
- {
- free(timer1);
- free(intfc_p->hwaddr);
- free(intfc_p->name);
- free(intfc_p);
- free(dcbp->rxbufp);
- free(dcbp);
- tprintf("tsync_attach error: no memory for IOCTL params size %x bytes, interface %s", sizeof(struct tsync_ioctl), argv[7]);
- return(-1);
- }
- }
- else
- {
- free(timer1);
- free(intfc_p->hwaddr);
- free(intfc_p->name);
- free(intfc_p);
- free(dcbp);
- tprintf("tsync_attach error: no memory for receive buffer, size %x bytes, interface %s", rbufsize, argv[7]);
- return(-1);
- }
- }
- else
- {
- free(timer1);
- free(intfc_p->hwaddr);
- free(intfc_p->name);
- free(intfc_p);
- tprintf("tsync_attach error: no memory for device control block structure, size of sizeof(DCB), interface %s", argv[7]);
- return(-1);
- }
-
-
- if ( Mycall[0] == '\0' )
- {
- free(timer1);
- free(intfc_p->hwaddr);
- free(intfc_p->name);
- free(intfc_p);
- free(dcbp->rxbufp);
- free(dcbp);
- tprintf("tsync_attach error: mycall not set\n");
- return(-1);
- }
-
-
- /*
- * Universal Driver Control Block Init -
- * Except for the saving of old vectors and attached field.
- * Attached field is saved for the very end.
- */
- udcbp->type = SYNC_8530; /* 8530 scc */
-
- /* set address of the unit's driver control block */
- udcbp->dcbp = (char *)dcbp;
-
- /* setup this device's interrupt handlers */
- udcbp->prev_vec2 = tsync_txisr;
- udcbp->prev_vec3 = tsync_rxisr;
- udcbp->prev_vec4 = tsync_xstatisr;
-
-
- /*
- * Setup the interface structure and link it to the list
- * of interface structures.
- */
- /* the Ascii name of the driver unit */
- strcpy(intfc_p->name,argv[7]);
-
- /* set the device number, must be able to tell whether */
- /* channel A or channel B is being used */
- dcbp->dev = udcb_dev;
- switch ( udcb_dev )
- {
- case TWINCOMM1:
- dcbp->zhwmap.ctl = (int16)(Twin_io_base+SCCA_CMD);
- dcbp->zhwmap.data = (int16)(Twin_io_base+SCCA_DATA);
- break;
-
- case TWINCOMM2:
- dcbp->zhwmap.ctl = (int16)(Twin_io_base+SCCB_CMD);
- dcbp->zhwmap.data = (int16)(Twin_io_base+SCCB_DATA);
- break;
-
- }
-
-
- /* not for NOS intfc_p->recv = tsync_recv;
- */
- intfc_p->mtu = xbufsize - MAX_AX25_HDR_LEN;
- intfc_p->ioctl = tsync_ioctl;
- intfc_p->raw = tsync_raw;
- intfc_p->addr = ipaddr; /* new for NOS */
- intfc_p->stop = tsync_stop;
- intfc_p->dev = udcb_dev;
-
- setencap(intfc_p,"AX25");
-
- /* For packet radio put in the sender's "call letters" */
- memcpy(intfc_p->hwaddr,Mycall,AXALEN);
-
- /* lastly, but very importantly, put in the LL of interfaces */
- intfc_p->next = Ifaces;
- Ifaces = intfc_p;
-
-
- /*
- * Initialize the unit's driver control block
- */
- dcbp->iface = intfc_p; /* new for NOS - save the iface */
- /* address for use in queueing */
- /* mbufs onto Hopper */
- dcbp->txstate = IDLE;
- dcbp->xmtq = (struct drvbuf *)NULLBUF;
- dcbp->xmtqtail = (struct drvbuf *)NULLBUF; /* milt */
- dcbp->freem = (struct drvbuf *)NULLBUF; /* milt */
-
- dcbp->rxstate = IDLE;
- dcbp->rxbufsize = atoi(argv[8]);
-
- /*milt 3/15/91
- dcbp->rxqhat.headp = NULLBUF;
- dcbp->rxqhat.tailp = NULLBUF;
- */
-
- /* Configure DMA stuff */
- dcbp->dma_flg = dmaflg;
- if(dmaflg == TRUE)
- {
-
- dcbp->dma_rx_chan = rxdmachan;
- dcbp->dma_tx_chan = txdmachan;
-
- switch(dcbp->dma_tx_chan)
- {
- case 1: dcbp->dma_tx_pagereg = 0x83;
- dcbp->dma_tx_cnt_reg = DMA1CNT;
- dcbp->dma_tx_addr_reg = DMA1ADR;
- break;
- case 3: dcbp->dma_tx_pagereg = 0x82;
- dcbp->dma_tx_cnt_reg = DMA3CNT;
- dcbp->dma_tx_addr_reg = DMA3ADR;
- break;
- }
-
- switch(dcbp->dma_rx_chan)
- {
- case 1: dcbp->dma_rx_pagereg = 0x83;
- dcbp->dma_rx_cnt_reg = DMA1CNT;
- dcbp->dma_rx_addr_reg = DMA1ADR;
- break;
- case 3: dcbp->dma_rx_pagereg = 0x82;
- dcbp->dma_rx_cnt_reg = DMA3CNT;
- dcbp->dma_rx_addr_reg = DMA3ADR;
- break;
- }
-
- /* SET up of the mode reg values for the DMA channels to be used */
- if(hdxflg == FALSE)
- {
- /* FULL DUPLEX the values never change between rx/tx */
- if(rxdmachan == 3)
- dcbp->dma_rx_mode = dcbp->dma_tx_mode = PKTWIN_DMA_FDX_T1R3;
- else
- dcbp->dma_rx_mode = dcbp->dma_tx_mode = PKTWIN_DMA_FDX_T3R1;
- }
- else
- {
- /* Half DUPLEX... */
- if(rxdmachan == 3)
- {
- dcbp->dma_rx_mode = PKTWIN_DMA_HDX_R3;
- dcbp->dma_tx_mode = PKTWIN_DMA_HDX_T3;
- }
- else
- {
- dcbp->dma_rx_mode = PKTWIN_DMA_HDX_R1;
- dcbp->dma_tx_mode = PKTWIN_DMA_HDX_T1;
- }
- }
-
- } /* End of dma info setup */
-
-
- /* no need to init stats because calloc zero-ed the dcbp */
-
- /* default IOCTL Params */
- dcbp->ioctlparams->xmitdelay = 250; /* 250 Ms */
- dcbp->ioctlparams->persist= 64; /* 25% of 255 = 64 persistance*/
- dcbp->ioctlparams->slotime = 10; /* 10 Ms */
- dcbp->ioctlparams->squelch = 200; /* 200 Ms */
-
- /* set the rxavailbufs parameter */
- dcbp->ioctlparams->rxavailbufs = 0; /* zero 1st */
- if ( argc >= 16 )
- dcbp->ioctlparams->rxavailbufs = atoi(argv[15]);
-
- if ( dcbp->ioctlparams->rxavailbufs < 4 )
- dcbp->ioctlparams->rxavailbufs = 4; /* 4 is min!! */
-
- /*
- * setup the packet header for the DRIVER
- * calling this routine
- */
- /* init to packet header's byte count */
- #ifdef OLD_KA9Q
- dcbp->rxbufp->cnt = sizeof(struct phdr);
- hdr = (struct phdr *)dcbp->rxbufp->data;
- hdr->type = intfc_p->type;
- hdr->iface = intfc_p;
- /* Rx data goes in after packet header */
- /* works because data is a char pointer */
- dcbp->rxbufp->data += sizeof(struct phdr);
- #else
- dcbp->rxbufp->cnt = 0;
- #endif
-
- dcbp->rxcurp = dcbp->rxbufp->data;
-
- /* get as many of the requested rx pre-allocated mbuf's */
- dcbp->rxavailq = NULLBUF;
-
- f_getavail(&(dcbp->rxavailq), dcbp->ioctlparams->rxavailbufs,
- dcbp->rxbufsize,
- &(dcbp->rxavailcount),
- intfc_p, dcbp->dma_flg);
-
- #ifdef TSYNC_DEBUG_PRT
- printf("TSYNC_ATTACH: rxavailbufs is %d, rxavailcount is %d\n", dcbp->ioctlparams->rxavailbufs, dcbp->rxavailcount);
- #endif
-
- /* put in the timer control blocks */
- dcbp->timer1 = timer1;
-
- dcbp->baud = (int16)atoi(argv[10]);
- /* set up duplex mode... */
- dcbp->hduplex = hdxflg;
-
-
- /* SET UP CLOCKING OPTIONS... */
- /* Default to Externally supplied clocks */
-
- /* select Tx clock mode for SCC */
- /* Default is to expect clock to be supplied externally */
- if((argc >= 12) && (strcmpi(argv[11],"int") == 0))dcbp->txclk_extrn = FALSE;
- else dcbp->txclk_extrn = TRUE;
-
- /* select Rx clock mode for SCC */
- /* Default is to expect clock to be supplied externally */
- if((argc >= 13) && (strcmpi(argv[12],"int") == 0))dcbp->rxclk_extrn = FALSE;
- else dcbp->rxclk_extrn = TRUE;
-
- /* select data coding scheme for SCC */
- /* Default is NRZ */
- if(argc >= 14)
- {
- if((strlen(argv[13]) >= strlen("nrzi")) &&
- (strcmpi(argv[13],"nrzi") == 0))
- {
- dcbp->nrzi_flg = TRUE;
- }
- else dcbp->nrzi_flg = FALSE;
- }
-
- /*
- * Now for the hardware dependent initializations.
- * If device control block is an 8530 driver, then SCC
- * stuff needs to be done.
- *
- * udcbp->type tells if its an 8530
- * intfc_p->dev tells which unit/dev
- *
- */
-
- #ifdef TSYNC_DEBUG_PRT
- printf("tsync_attach: intfc_p->dev = %x config 8530 HW \n", intfc_p->dev);
- #endif
-
-
- i_state = dirps(); /* {dgl} protect the writescc's */
- /* and the vector reads/writes */
- /* disable our ints */
- maskoff(Twin_vector);
- outportb(Twin_io_base+INT_CFG,(Twin_sercfg &= (~PKTWIN_EI)));
-
-
- /*
- * Can only reset the chip when it is not being used!!!
- * This handles first time use of 8530.
- * Set the base vector - since it is common set it here.
- */
-
-
- if ( (Twin_udcb[TWINCOMM1].attached == FALSE) &&
- (Twin_udcb[TWINCOMM2].attached == FALSE) )
- {
-
- /* This should NOT be done... if either ports are in use */
- /* for ANYTHING */
- Twin_write_scc(dcbp->zhwmap.ctl,R9,(dcbp->wr9 = FHWRES));
-
-
- /* Save original interrupt vector */
- Twin_oldvec = (INTERRUPT (*)())getirq(Twin_vector);
-
- udcbp->prev_vec1 = (void (*)())Twin_oldvec;
-
- /* New vector... */
- setirq(Twin_vector, Twin_handler);
-
- /* set up register images, and regs to defaults */
-
- Twin_sercfg = Twin_dmacfg = 0;
- outportb(Twin_io_base+INT_CFG,Twin_sercfg);
- outportb(Twin_io_base+DMA_CFG,Twin_dmacfg);
- }
- /*
- * Reset the individual channel. Handles cases of re-attaching
- * channels and first attachment.
- *
- * For safetys sake set the Disable Lower Chain bit too.
- */
- if ( dcbp->dev == TWINCOMM1 )
- Twin_write_scc(dcbp->zhwmap.ctl,R9,(dcbp->wr9 = 0x84));
- else
- Twin_write_scc(dcbp->zhwmap.ctl,R9,(dcbp->wr9 = 0x44));
-
- /* wait a bit... for chip to settle after reset */
- /* Just in case... */
- for(i=0;i<20;i++); /* milt */
-
- /* configure the 8530 SCC */
- if(tsync_hwinit(dcbp) == -1)
- {
- /* An error occurred in the hw init */
- /* so clean up and leave... */
-
- /* Mark it attached so the following detach routine */
- /* won't complain */
- udcbp->attached = TRUE;
- if_detach(intfc_p);
-
- /* re-enable this interrupt input */
- maskon(Twin_vector);
-
- restore(i_state);
- tprintf("PackeTwin hardware unavailable or malfunctioning...\n");
- return(-1);
- }
-
-
- /* enable PackeTwin ints */
- outportb(Twin_io_base+INT_CFG,(Twin_sercfg |= PKTWIN_EI));
-
- /* enable this level ints on 8259 */
- maskon(Twin_vector);
-
- /* {dgl} enable system-wide ints */
- restore(i_state);
-
- /*
- * This channel is ATTACHED.
- */
- udcbp->attached = TRUE;
-
-
- /* new for NOS - start the two processes needed by the */
- /* sync driver; one is for getting pre-allocated buffers */
- /* the other is for kicking the transmitter after its */
- /* timer has expired or when it needs a transmitted */
- /* message free-ed. P.S. must do after attached set to TRUE */
-
- sprintf(tmpbuf,"%s:getbuf",intfc_p->name);
- dcbp->rxavproc = newproc(tmpbuf,150,tsync_rxavget,udcb_dev,NULL,NULL,0);
-
- #ifdef TSYNC_DEBUG_PRT
- printf("tsync_attach: called newproc for tsync_getbfs, procid = %lx \n",
- dcbp->rxavproc);
- #endif
-
-
- sprintf(tmpbuf,"%s:kick",intfc_p->name);
- dcbp->txkickproc = newproc(tmpbuf,150,tsync_txkick,udcb_dev,NULL,NULL,0);
-
- #ifdef TSYNC_DEBUG_PRT
- printf("tsync_attach: called newproc for tsync_txkick, procid = %lx \n",
- dcbp->txkickproc);
-
- tprintf("tsync_attach: All done!!! \n");
- #endif
- sprintf(tmpbuf,"%s:free",intfc_p->name);
- dcbp->freetxproc = newproc(tmpbuf,150,tsync_freetx,udcb_dev,NULL,NULL,0);
-
- /* Let our new processes get running... */
- for(i=0;i<10;i++)pwait(NULL);
-
- return(0);
- }
- /*
- * End of tsync_attach()
- ******************************************************************/
-
-
-
- /*
- * Stop I/O
- */
- int
- tsync_stop(intfcp)
- struct iface *intfcp;
- {
- DCB *sp;
- UNI_DCB *udcbp;
- int16 dev;
- char i_state;
- struct drvbuf *xbufp, *tmpptr;
- struct mbuf *tmpbufp;
-
-
- dev = intfcp->dev;
- udcbp = &Twin_udcb[dev]; /* dev num is index number!!! */
-
- if ( udcbp->attached != TRUE )
- {
- tprintf("tsync_stop err: Device already stopped/de-attached!!\n");
- return(0);
- }
- else if ( (dev != TWINCOMM1) && (dev != TWINCOMM2) )
- return(0); /* not for this driver */
-
- sp = (DCB *)Twin_udcb[dev].dcbp;
-
- /* kill off the support processes */
- /* so they don't allocate memory */
- /* whils't we're freeing it */
-
- killproc(sp->rxavproc);
- killproc(sp->txkickproc);
- killproc(sp->freetxproc);
-
- /* Turn off interrupts */
-
- i_state = dirps();
-
- /* mark port as available - do it now for if below */
- udcbp->attached = FALSE;
-
-
-
- /* Disable the DMA channels if any... */
- if(sp->dma_flg)
- {
- outportb(DMAWSMR,sp->dma_rx_chan | 0x04);
- outportb(DMAWSMR,sp->dma_tx_chan | 0x04);
- }
-
- /*
- * Can only reset the chip when it is not being used!!!
- * This handles first time use of 8530.
- * Set the base vector - since it is common set it here.
- */
-
-
- if ( (Twin_udcb[TWINCOMM2].attached == FALSE) &&
- (Twin_udcb[TWINCOMM1].attached == FALSE) )
- {
-
- /* This should NOT be done... if either ports are in use */
- /* for ANYTHING */
- Twin_write_scc(sp->zhwmap.ctl,R9,(sp->wr9 = FHWRES));
-
- /* Restore original interrupt vector */
- setirq(Twin_vector,(INTERRUPT (*)())udcbp->prev_vec1);
-
- /* Disable our board from generating ints... */
- outportb(Twin_io_base+INT_CFG,(Twin_sercfg &= (~PKTWIN_EI)));
- }
-
- /*
- * Reset the individual channel. Handles cases of re-attaching
- * channels and first attachment.
- *
- */
-
- if ( sp->dev == TWINCOMM1 )
- {
- Twin_write_scc(sp->zhwmap.ctl,R9,(sp->wr9 = 0x88));
-
- /* Drop DTR to indicate we are gone...*/
- outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg &= (~PKTWIN_DTRA_ON)));
- }
- else
- {
- Twin_write_scc(sp->zhwmap.ctl,R9,(sp->wr9 = 0x48));
- /* Drop DTR to indicate we are gone...*/
- outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg &= (~PKTWIN_DTRB_ON)));
- }
-
- restore(i_state);
-
- /*
- * Flush all buffers and queue's
- */
-
- /* Now free all preallocated rx buffers on the rx available queue */
- while((tmpbufp = f_dequeavail(&sp->rxavailq,&sp->rxavailcount)) != NULLBUF)
- free(tmpbufp); /* these mbuf's are one contigous */
- /* chunk of memory */
-
-
- if ( sp->rxbufp != NULLBUF )
- free(sp->rxbufp);
-
- /* free up any pending transmit buffers... */
- while(sp->xmtq != (struct drvbuf *)NULLBUF)
- {
- tmpptr = sp->xmtq->next;
- free(sp->xmtq);
- sp->xmtq = tmpptr;
- }
-
- /* Free any previously sent frames, which are in the waiting to be */
- /* free'd queue */
-
- /* disable ints here to get queue head... */
- i_state = dirps(); /* seems unecessary milt */
- xbufp = sp->freem;
- sp->freem = (struct drvbuf *)NULLBUF;
- restore(i_state);
-
- /* Here xbufp is a "to be free'd" */
- /* queue pointer" */
- /* now free memory of all the xmitted messages */
- while ( xbufp != (struct drvbuf *)NULLBUF )
- {
- tmpptr = xbufp->next;
- free((char *)xbufp);
- xbufp = tmpptr;
- }
-
-
-
- /*
- * Deallocate other driver related memory structures
- */
- free(sp->timer1);
- free(sp->ioctlparams);
- free(sp);
-
- return(0);
- }
-
-
- /*
- * Display a PackeTwin SYNCHRONOUS channel's statistics.
- */
- int
- do_tsync_stat()
- {
- DCB *dcbp;
- UNI_DCB *udcbp;
- int16 dev;
- unsigned long rxerrcnt;
- bool hd8530;
-
- /* Header for all the Synchronous channel's on the card */
- tprintf(" PackeTwin Synchronous Driver Release %s\n\n"
- ,Twin_dvr_version);
-
- hd8530 = FALSE;
- for (dev=0, udcbp = &Twin_udcb[0]; dev < 2 ; udcbp++, dev++)
- {
- if ( udcbp->type == SYNC_8530 )
- {
- if ( udcbp->attached == TRUE )
- {
- if ( !hd8530 )
- {
- tprintf("\n");
- tprintf("8530 RxChars RxPacks Rxerrs RxBf Txchars TxPacks TxUns RxNoBf\n");
- tprintf("----- --------- ------- ------ ---- --------- ------- ----- ------\n");
- hd8530 = TRUE;
- }
-
- dcbp = (DCB *)udcbp->dcbp;
- /* total receiver error count */
- rxerrcnt = dcbp->rxcrcerrcnt + dcbp->rxovercnt;
-
- tprintf(" %4.1d %#9lu %#7lu %#6lu %#4lu %#9lu %#7lu %#5lu %#6lu\n",
- dev, dcbp->rxbytecnt,
- dcbp->rxpackcnt,
- rxerrcnt,
- dcbp->rxavailcount,
- dcbp->txbytecnt,
- dcbp->txpackcnt,
- dcbp->txunderun,
- dcbp->nobufs);
-
- #ifdef TSYNC_DEBUG_PRT
- printf("Crc's: %lx Overruns: %lx\n",dcbp->rxcrcerrcnt,dcbp->rxovercnt);
- printf("DCB ptr: %p\n",dcbp);
- printf("rxcurp: %p rxbufp: %p rxbufp->cnt: %d\n",dcbp->rxcurp,
- dcbp->rxbufp,
- dcbp->rxbufp->cnt);
-
- #endif
- }
- }
-
- } /* end of for loop */
-
- for (dev=0, udcbp = &Twin_udcb[0]; dev < 2; udcbp++, dev++)
- {
- if ( udcbp->attached == FALSE )
- tprintf("\nChannel %d is UN-attached", dev);
- }
-
- tprintf("\n");
- return(0);
- }
-
- /* Subroutine to set kiss params in channel tables */
- int32
- tsync_ioctl(iface,cmd,set,val)
- struct iface *iface;
- int cmd;
- int set;
- int32 val;
- {
- DCB *dcbp;
-
- dcbp = (DCB *)Twin_udcb[iface->dev].dcbp;
-
- switch(cmd){
- case PARAM_TXDELAY:
- if(set)
- dcbp->ioctlparams->xmitdelay = (int16)val;
- return dcbp->ioctlparams->xmitdelay;
-
- case PARAM_PERSIST:
- if(set)
- dcbp->ioctlparams->persist = (uchar)val;
- return uchar(dcbp->ioctlparams->persist);
- case PARAM_SLOTTIME:
- if(set)
- dcbp->ioctlparams->slotime = (int16)val;
- return dcbp->ioctlparams->slotime;
- case PARAM_TXTAIL:
- if(set)
- dcbp->ioctlparams->squelch = (int16)val;
- return dcbp->ioctlparams->squelch;
-
- case PARAM_RXBUFS:
- if(set)
- dcbp->ioctlparams->rxavailbufs = (int16)val;
- return dcbp->ioctlparams->rxavailbufs;
-
- }
- return -1;
- }
-
- /*
- * Initialize the SZ driver's hardware for SDLC, i.e. the 85c30 SCC.
- */
- int
- tsync_hwinit(dcbp)
- register DCB *dcbp;
- {
- char i_state; /* for PackeTwin this is 2 bytes */
- int16 tc; /* time constant for 8530 */
- int i;
- bool baudclk_flg;
- bool both_clocks_internal;
- void tsync_loopback();
- void enable_escc();
- int nop1 = 0;
-
- #define nop nop1++;
-
-
- #ifdef TSYNC_DEBUG_PRT
- printf("Initializing TSYNC_DRIVER device num = %d\n", dcbp->dev);
- #endif
- i_state = dirps();
-
-
- /* if both clocks are specified as internal, then override the */
- /* specified data coding scheme, and MAKE it NRZI */
- if((dcbp->rxclk_extrn == FALSE) && (dcbp->txclk_extrn == FALSE))
- {
- dcbp->nrzi_flg = TRUE;
- both_clocks_internal = TRUE;
- }
- else
- both_clocks_internal = FALSE;
-
- /* If we are not using DMA, then try to enable the extended TX FIFO */
- if(!(dcbp->dma_flg)) enable_escc(dcbp);
-
- /* times 1 x clock, SDLC mode */
- /* always set R4 before R1, R3, R6, and R7 */
- Twin_write_scc(dcbp->zhwmap.ctl,R4,(dcbp->wr4 = 0x20));
-
- /* mask-off all interrupt types */
- /* No DMA, No Ints... */
- Twin_write_scc(dcbp->zhwmap.ctl,R1,(dcbp->wr1 = 0));
-
- /* Rx 8 bit/chars, enter hunt mode, CRC enable */
- Twin_write_scc(dcbp->zhwmap.ctl,R3,(dcbp->wr3 = 0xd8));
-
- /* DTR, Tx 8 bit/chars and Tx disabled */
- Twin_write_scc(dcbp->zhwmap.ctl,R5,(dcbp->wr5 = 0x60));
-
- /* no SDLC transmit secondary address */
- Twin_write_scc(dcbp->zhwmap.ctl,R6,(dcbp->wr6 = 0));
-
- /* Set SDLC flag */
- Twin_write_scc(dcbp->zhwmap.ctl,R7,(dcbp->wr7 = FLAG));
-
- if(dcbp->nrzi_flg != TRUE)
- {
- /* Preset Tx CRC, NRZ Mode, flags on idle and */
- /* underrun 8 bit sync mode */
- Twin_write_scc(dcbp->zhwmap.ctl,R10,(dcbp->wr10 = 0x84));
- }
-
- else
- {
- /* Preset Tx CRC, NRZI Mode, flags on idle and */
- /* aborts on underrun 8 bit sync mode */
- Twin_write_scc(dcbp->zhwmap.ctl,R10,(dcbp->wr10 = 0xa4));
- }
-
- /* Set up BRG and DPLL multiplexers */
-
- /* Case where only the Rx clock is supplied externally */
- if((dcbp->rxclk_extrn == TRUE) && (dcbp->txclk_extrn != TRUE))
- {
- /* Tx Clk from BRG. Rcv Clk external on RTxC, */
- /* TRxC pin outputs BRgen */
- Twin_write_scc(dcbp->zhwmap.ctl,R11,(dcbp->wr11 = 0x16));
- tc = ( (XTAL) / (dcbp->baud *2))-2;
- baudclk_flg = TRUE;
-
- /* disable the external TX clock receiver input */
- if(dcbp->dev == TWINCOMM1) outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg &= (~PKTWIN_EXTCLKA)));
- else outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg &= (~PKTWIN_EXTCLKB)));
- }
-
- /* Case where only the Tx clock is supplied externally */
- if((dcbp->txclk_extrn == TRUE) && (dcbp->rxclk_extrn != TRUE))
- {
- /* Tx Clk external on TRxC, Rcv Clk internal BRgen, */
- /* TRxC pin is input TX clock */
- Twin_write_scc(dcbp->zhwmap.ctl,R11,(dcbp->wr11 = 0x4a));
- tc = ( (XTAL) /(dcbp->baud *2))-2;
- baudclk_flg = TRUE;
-
- /* enable the external TX clock receiver input */
- if(dcbp->dev == TWINCOMM1) outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg |= PKTWIN_EXTCLKA));
- else outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg |= PKTWIN_EXTCLKB));
- }
-
- /* Case where both clocks are supplied externally */
- if((dcbp->txclk_extrn == TRUE) && (dcbp->rxclk_extrn == TRUE))
- {
- /* Tx Clk external on TRxC, Rcv Clk external on RTxC, */
- /* TRxC pin is input TX clock */
- Twin_write_scc(dcbp->zhwmap.ctl,R11,(dcbp->wr11 = 0x0a));
- baudclk_flg = FALSE;
-
- /* enable the external TX clock receiver input */
- if(dcbp->dev == TWINCOMM1) outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg |= PKTWIN_EXTCLKA));
- else outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg |= PKTWIN_EXTCLKB));
-
- /*DTR is in REQ mode for possible DMA */
- if(dcbp->dma_flg)Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0x04));
- else Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0x00));
- }
-
- if(both_clocks_internal == TRUE)
- {
- /* Tx Clk from BRG. Rcv Clk from DPLL, TRxC pin outputs DPLL */
- Twin_write_scc(dcbp->zhwmap.ctl,R11,(dcbp->wr11 = 0x77));
-
- /* time constant 32X BRG divisor */
- tc = ((XTAL/32)/(dcbp->baud * 2))-2;
- /* DGL... fix a cut and paste error... */
- /* baudclk_flg = FALSE; */
- baudclk_flg = TRUE;
-
- /* disable the external TX clock receiver input */
- if(dcbp->dev == TWINCOMM1) outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg &= (~PKTWIN_EXTCLKA)));
- else outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg &= (~PKTWIN_EXTCLKB)));
-
- }
-
- if(baudclk_flg == TRUE)
- {
-
- /* lower byte */
- Twin_write_scc(dcbp->zhwmap.ctl,R12,(dcbp->wr12 = (tc&0xFF)));
-
- /* upper byte */
- Twin_write_scc(dcbp->zhwmap.ctl,R13,(dcbp->wr13 = ((tc>>8)&0xFF)));
-
- /* enable the BR generator... */
- /*DTR is in REQ mode for possible DMA */
- if(dcbp->dma_flg)Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0x07));
- else Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0x03));
- }
-
-
- if(both_clocks_internal == TRUE)
- {
-
- /* BRG off, Enter Search mode */
- /*DTR is in REQ mode if possible DMA */
- if(dcbp->dma_flg)Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0x26));
- else Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0x22));
-
- /* Set DPLL source to BRGEN */
- /*DTR is in REQ mode for possible DMA */
- if(dcbp->dma_flg)Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0x86));
- else Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0x82));
-
- /* Set DPLL mode to NRZI */
- /*DTR is in REQ mode for possible DMA */
- if(dcbp->dma_flg)Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0xe6));
- else Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0xe2));
-
-
-
- /* At this point; the DPLL is searching for a data edge to begin clocking */
- /* The baud rate gen is set to 32 times the desired rate.. */
- /* The transmitter is based on the BRGEN. (i.e. 32x ) */
- /* */
- /* Procedure here; Set up an external loopback, then send aborts, to */
- /* trigger and sync up the DPLL. */
- /* After the DPLL is running, then reprogram the Xmitter */
- /* to use the DPLL output as it's transmitter clock. */
- /* This saves us having to reprogram the BRG whenever we */
- /* switch from RECV to TX and back. */
- /*
-
- /* Turn on the recvr */
- /* Rx 8 bit/chars, enter hunt mode, CRC enable */
- Twin_write_scc(dcbp->zhwmap.ctl,R3,(dcbp->wr3 = 0xd9));
-
- /* Turn on the transmitter */
- /* DTR, Tx 8 bit/chars and Tx enabled */
- Twin_write_scc(dcbp->zhwmap.ctl,R5,(dcbp->wr5 = 0x68));
-
- /* reset TX CRC */
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = 0x80));
-
- /* enable the BR generator to start things up...*/
- /*DTR is in REQ mode for possible DMA */
- if(dcbp->dma_flg)Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0x07));
- else Twin_write_scc(dcbp->zhwmap.ctl,R14,(dcbp->wr14 = 0x03));
-
-
- /* OK now turn on the loopback */
- tsync_loopback(dcbp,ON);
-
- /* Now send sum aborts... */
-
- for(i=0;i<25;i++)
- {
-
- /* read and toss any data */
- inportb(dcbp->zhwmap.data);
- inportb(dcbp->zhwmap.data);
- inportb(dcbp->zhwmap.data);
- inportb(dcbp->zhwmap.data);
-
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = 0x18)); /* send abort */
- }
-
- /* OK, now the DPLL should be running at ~32 * baudrate requested */
- /* Turn off the loopback... */
-
- tsync_loopback(dcbp,OFF);
-
-
- /* Now reprogram the transmitter clock to use the DPLL output */
-
- /* TX clk is DPLL, RX clk is DPLL, TRxc is DPLL OUT */
- Twin_write_scc(dcbp->zhwmap.ctl,R11,(dcbp->wr11 = 0x7f));
-
- /* dgl for G3RUH modems... I need to do AUTO-ENABLES... */
- Twin_write_scc(dcbp->zhwmap.ctl,R3,(dcbp->wr3 = 0xf9));
-
-
- }
-
- else
- {
-
- /* Turn on the recvr */
- /* Rx 8 bit/chars, enter hunt mode, CRC enable */
-
- /* no autoenables */
- /*
- Twin_write_scc(dcbp->zhwmap.ctl,R3,(dcbp->wr3 = 0xd9));
- */
-
- /* dgl for G3RUH modems... I need to do AUTO-ENABLES... */
- Twin_write_scc(dcbp->zhwmap.ctl,R3,(dcbp->wr3 = 0xf9));
-
- }
-
- /* Turn off external interrupts (like CTS/CD) */
- Twin_write_scc(dcbp->zhwmap.ctl,R15,(dcbp->wr15 = 0x00));
-
-
- /* TRANSMITTER OFF */
- Twin_write_scc(dcbp->zhwmap.ctl,R5,(dcbp->wr5 = 0x60)); /* TX off now */
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = 0x80)); /* reset TX CRC generator */
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = 0x40)); /* reset RX CRC checker */
-
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = 0x28)); /* reset TX int pending */
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = 0x28)); /* reset TX int pending */
-
-
- /* reset extrn/sts ints... twice */
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = 0x10));
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = 0x10));
-
- /* if we are interrupt driven only: then allow ints for ALL RCV cndxs,
- */
- if(dcbp->dma_flg == FALSE)
- Twin_write_scc(dcbp->zhwmap.ctl,R1,(dcbp->wr1 = 0x11));
-
- /* otherwise interrupt on special rcv cdx only */
- /* DMA req mode Req on rcv, Req enabled */
- else Twin_write_scc(dcbp->zhwmap.ctl,R1,(dcbp->wr1 = 0xf9));
-
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = 0x30)); /* reset error bits */
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = 0x30)); /* twice superstition */
-
- /* If neither of the PKTwin's ports are currently attached*/
- /* Then set up the prescaler timer */
- if ( (Twin_udcb[TWINCOMM2].attached == FALSE) &&
- (Twin_udcb[TWINCOMM1].attached == FALSE) )
- {
- inportb(Twin_io_base+CLR_TMR1);
- nop;
- inportb(Twin_io_base+CLR_TMR2);
- nop;
-
- /* Timer counter channel 0 */
- /* 1 ms period */
- outportb(Twin_io_base+TMR_CTRL,(unsigned char)0x36);
- nop;
- outportb(Twin_io_base+TMR_CNT0,(unsigned char)0x00);
- nop;
- outportb(Twin_io_base+TMR_CNT0,(unsigned char)0x18);
- nop;
-
- outportb(Twin_io_base+TMR_CTRL,(unsigned char)0x70);
- nop;
- inportb(Twin_io_base+CLR_TMR1);
- nop;
-
- outportb(Twin_io_base+TMR_CTRL,(unsigned char)0xB0);
- nop;
- inportb(Twin_io_base+CLR_TMR2);
- nop;
- }
-
- if(dcbp->dev == TWINCOMM1)
- {
- /* mode setup for this channel's driver timer */
- /* Set it's timer for 1 tick and let it expire */
- outportb(Twin_io_base+TMR_CTRL,(unsigned char)0x70);
- nop;
- inportb(Twin_io_base+CLR_TMR1);
- nop;
-
-
- /* If the timer hasn't gone off, the hardware is either */
- /* not present, or broken... */
- if(!inportb(Twin_io_base+INT_REG) & 0x02)
- {
- restore(i_state);
- return(-1);
- }
-
- /* Assert DTR to indicate we are alive...*/
- outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg |= PKTWIN_DTRA_ON));
-
- }
- if(dcbp->dev == TWINCOMM2)
- {
- /* mode setup for this channel's driver timer */
- outportb(Twin_io_base+TMR_CTRL,(unsigned char)0xb0);
- nop;
- inportb(Twin_io_base+CLR_TMR2);
- nop;
- /* If the timer hasn't gone off, the hardware is either */
- /* not present, or broken... */
- if(!inportb(Twin_io_base+INT_REG) & 0x04)
- {
- restore(i_state);
- return(-1);
- }
- nop;
- /* Assert DTR to indicate we are alive...*/
- outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg |= PKTWIN_DTRB_ON));
- }
-
- if(dcbp->dma_flg == TRUE)
- {
- /* mask off the DMA channel(s) */
- outportb(DMAWSMR,(dcbp->dma_rx_chan | 0x04));
- outportb(DMAWSMR,(dcbp->dma_tx_chan | 0x04));
-
- outportb(Twin_io_base+DMA_CLR_FF,0x00); /* Initially clear the REQ's */
- /* This is the PackeTwin reg..*/
- /* NOT the 8237 reg... */
- outportb(DMAMODE,dcbp->dma_rx_chan | RX_DMA);
-
- if(dcbp->hduplex == FALSE)
- {
- outportb(DMAMODE,dcbp->dma_rx_chan | RX_DMA);
- outportb(DMAMODE,dcbp->dma_tx_chan | TX_DMA);
- /* tx dma, enabled, fdx, chan3*/
- /* rx dma, enabled, fdx, chan1*/
- outportb(Twin_io_base+DMA_CFG,dcbp->dma_tx_mode);
-
- }
- else
- {
- outportb(DMAMODE,dcbp->dma_rx_chan | RX_DMA);
- /* rx dma,hdx, enabled, chan 1*/
- outportb(Twin_io_base+DMA_CFG,dcbp->dma_rx_mode);
- }
- outportb(DMAFFCL,0x00); /* This is the 8237 reg */
-
- rxprime_dma(dcbp,1); /* buglet... 9/12/92 */
- /* {dgl} */
- }
-
- /* reset Tx int pending */
- /* This should keep the chip from underrunning, as */
- /* well as clearing any pending txempty interrupt */
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = 0x28));
-
- /* reset external status latch */
- /* clear any pending ext sts bits */
- /* TWICE for good measure */
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = RES_EXT_INT));
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = RES_EXT_INT));
-
- /* Reset Underrun/EOM latch */
- /* clear the latch... it should stay that way...*/
- /* at least till we send feed some data to the tx fifo */
- Twin_write_scc(dcbp->zhwmap.ctl,R0,(dcbp->wr0 = (RES_EOM_L | RES_EXT_INT)));
-
- /* Turn on DCD interrupt */
- Twin_write_scc(dcbp->zhwmap.ctl,R15,(dcbp->wr15 = CTSIE|DCDIE));
-
- /* save this initial state of RR0 */
- dcbp->extreg = Twin_read_scc(dcbp->zhwmap.ctl,R0);
- dcbp->extreg = dcbp->extreg |= TxEOM;
-
- /* if we are interrupt driven only: then allow ints for ALL RCV cndxs,
- */
- if(dcbp->dma_flg == FALSE)
- Twin_write_scc(dcbp->zhwmap.ctl,R1,(dcbp->wr1 = 0x13));
-
- /* otherwise interrupt on special rcv cdx only */
- /* DMA req mode Req on rcv, Req enabled */
- else Twin_write_scc(dcbp->zhwmap.ctl,R1,(dcbp->wr1 = 0xf9));
-
- /* master interrupt enable the channel */
- Twin_write_scc(dcbp->zhwmap.ctl,R9,(dcbp->wr9 = (MIE|DLC|NV)));
-
- restore(i_state);
- return(0);
- }
-
- void
- tsync_loopback(dcbp,flag)
- DCB *dcbp;
- char flag;
- {
- if(flag == ON)
- {
- switch(dcbp->dev)
- {
- case TWINCOMM1: outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg |= PKTWIN_LOOPA_ON));
- break;
-
- case TWINCOMM2: outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg |= PKTWIN_LOOPB_ON));
- break;
- }
- }
- else
- {
- switch(dcbp->dev)
- {
- case TWINCOMM1: outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg &= (~PKTWIN_LOOPA_ON)));
- break;
-
- case TWINCOMM2: outportb(Twin_io_base+SERIAL_CFG,(Twin_sercfg &= (~PKTWIN_LOOPB_ON)));
- break;
- }
- }
-
- }
-
-
- void
- tsync_reset_8530()
- {
-
- int16 ctl;
-
- ctl = (int16)(Twin_io_base+SCCA_CMD);
- Twin_write_scc(ctl,R9,FHWRES);
-
- }
-
- /*
- 1 2 3 4 5 6 7
- 01234567890123456789012345678901234567890123456789012345678901234567890123456789
- /*
- * Display a PackeTwin SYNCHRONOUS channel's internal state
- */
- int
- do_tsync_dump(argc,argv,p)
- int argc;
- char *argv[];
- void *p; /* new for NOS */
- {
- DCB *dcbp;
- UNI_DCB *udcbp;
- int16 dev;
- char tmpstr[40];
-
- if(argc < 2)
- {
- tprintf("Usage: tsydump channel#\n");
- return 1;
- }
-
- dev = htoi(argv[1]); /* get port number to look at */
-
- tprintf(" PackeTwin Synchronous Channel Internals\n\n");
-
- udcbp = &Twin_udcb[dev];
- if ( udcbp->type == SYNC_8530 )
- {
- if ( udcbp->attached == TRUE )
- {
- dcbp = (DCB *)udcbp->dcbp;
- tprintf("\n");
- tprintf(" RECEIVER STATUS: \n");
- tprintf(" Packcnt Nqued Bytecnt Availcount Nobufs\n");
- tprintf("%#8ld %#8ld %#8ld %#8ld %#8ld\n",
- dcbp->rxpackcnt,dcbp->rxnqued,
- dcbp->rxbytecnt,dcbp->rxavailcount,dcbp->nobufs);
-
- tprintf("\n"); /* blank line */
- tprintf(" Overcnt Abortcnt Crcerrcnt Truncnt\n");
- tprintf("%#8ld %#8ld %#8ld %#8ld\n",
- dcbp->rxovercnt,dcbp->rxabortcnt,
- dcbp->rxcrcerrcnt,dcbp->rxtruncnt);
-
- tprintf("\n"); /* blank line */
-
- switch(dcbp->txstate)
- {
- case IDLE:
- strcpy(tmpstr,"IDLE");
- break;
-
- case DEFER:
- strcpy(tmpstr,"DEFER");
- break;
-
- case TX_ACTIVE:
- strcpy(tmpstr,"TX_ACTIVE");
- break;
-
- case KEYED_UP:
- strcpy(tmpstr,"KEYED_UP");
- break;
-
- case CRCING:
- strcpy(tmpstr,"CRCING");
- break;
-
- case TX_KEYUP_DELAY:
- strcpy(tmpstr,"TX_KEYUP_DELAY");
- break;
-
- case TX_KEYDOWN_DELAY:
- strcpy(tmpstr,"TX_KEYDOWN_DELAY");
- break;
-
- case TX_PERSIST:
- strcpy(tmpstr,"TX_PERSIST");
- break;
-
- case TX_DONE:
- strcpy(tmpstr,"TX_DONE");
- break;
-
- default:
- strcpy(tmpstr,"UNKNOWN STATE");
- break;
-
- }
-
- tprintf(" TRANSMITTER STATUS:\n");
- tprintf(" Packcnt Bytecnt Underrun Cur_xbufp Cur_xbytes MxFIFO TX STATE\n");
-
- tprintf("%8ld %8ld %8ld %8lx %8d %2.2d ",
- dcbp->txpackcnt,dcbp->txbytecnt,
- dcbp->txunderun,dcbp->cur_xbufp,
- dcbp->cur_xbytes,dcbp->maxtxbytes);
- tprintf("%s\n",tmpstr);
-
- tprintf("\n"); /* blank line */
- tprintf(" CTSlost: %d\n",dcbp->txctslost);
- tprintf("\n"); /* blank line */
-
- tprintf( "WR0 WR1 WR2 WR3 WR4 WR5 WR6 WR7 WR8 WR9 WR10 WR11 WR12 WR13 WR14 WR15");
-
-
- tprintf(" %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x",
- dcbp->wr0,dcbp->wr1,dcbp->wr2,dcbp->wr3,dcbp->wr4,
- dcbp->wr5,dcbp->wr6,dcbp->wr7,0,dcbp->wr9,
- dcbp->wr10,dcbp->wr11,dcbp->wr12,dcbp->wr13,dcbp->wr14,
- dcbp->wr15);
-
- tprintf("\n");
- tprintf("\n");
-
- tprintf("Extsts Extreg Hduplex Dma_flg Txclk_extrn Rxclk_extrn Nrzi_flg\n");
- tprintf(" %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
- dcbp->extsts,dcbp->extreg,dcbp->hduplex,
- dcbp->dma_flg,dcbp->txclk_extrn,
- dcbp->rxclk_extrn,dcbp->nrzi_flg);
-
-
- tprintf("\n");
-
- tprintf("Dma_rx_chan Dma_rx_mode Dma_rx_pagereg Dma_rx_cnt_reg Dma_rx_addr_reg\n");
-
- tprintf( " %2.2x %2.2x %2.2x %2.2x %2.2x\n",
- dcbp->dma_rx_chan,dcbp->dma_rx_mode,
- dcbp->dma_rx_pagereg,dcbp->dma_rx_cnt_reg,
- dcbp->dma_rx_addr_reg);
-
- tprintf("Dma_tx_chan Dma_tx_mode Dma_tx_pagereg Dma_tx_cnt_reg Dma_tx_addr_reg\n");
- tprintf( " %2.2x %2.2x %2.2x %2.2x %2.2x\n",
- dcbp->dma_tx_chan,dcbp->dma_tx_mode,
- dcbp->dma_tx_pagereg,dcbp->dma_tx_cnt_reg,
- dcbp->dma_tx_addr_reg);
-
- }
- else tprintf("Channel %d: is UN-attached!\n",dev);
- }
-
-
- tprintf("\n");
- return(0);
- }
-
- /* 85230 Mods: Call this routine to enable the Deeper TX fifo... */
- /* Do it BEFORE you set up WR7 (sync char), cause it will trash */
- /* WR7 if the installed chip is actually an 85c30 or 8530 instead*/
- /* of an 85230 */
- void
- enable_escc(dcbp)
- register DCB *dcbp;
- {
-
- /* try to enable the escc extended registers */
- Twin_write_scc(dcbp->zhwmap.ctl,R15,0x01);
-
- /* Set up the TX FIFO to generate an interrupt as soon */
- /* as there is ANY room in the FIFO. Rather than the default */
- /* of when the FIFO is empty. */
-
- /* If this is just an SCC, then the R7 will be overwritten */
- /* by the real init code later..., but if not, */
- /* then this is R7' for FIFO control */
- Twin_write_scc(dcbp->zhwmap.ctl,R7,0x00);
-
- /* restore the WR15 to an acceptable value for an 8530 */
- Twin_write_scc(dcbp->zhwmap.ctl,R15,0x00);
- }
-